package com.qf.juc.demo;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class ConcurrentHashMapDemo {

    // ConcurrentModificationException 并发修改异常 解决方案
    public static void main(String[] args) {
//        hashMap();
//        hashTable();
//        collections();
        concurrentHashMap();
    }


    /**
     * 1、会产生ConcurrentModificationException 并发修改异常
     */
    public static void hashMap(){
        Map<String,String> map = new HashMap<>();

//        Runnable runnable = ()->{
//
//        };

        for (int i = 1; i < 30; i++) {
            new Thread(()->{
                map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,5));
                System.err.println("当前线程为："+Thread.currentThread().getName()+":"+"\n"+map);
            },String.valueOf(i)).start();

        }

    }

    /**
     * 2、能够解决并发安全问题，但是效率比较低
     */

    public static void hashTable(){
        Map<String,String> map = new Hashtable<>();

        for (int i = 1; i < 30; i++) {
            new Thread(()->{
                map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,5));
                System.err.println("当前线程为："+Thread.currentThread().getName()+":"+"\n"+map);
            },String.valueOf(i)).start();

        }

    }

    /**
     * 3、能够解决并发安全问题，效率比较高
     */

    public static void collections(){
        Map<String,String> map = Collections.synchronizedMap(new HashMap<>());

        for (int i = 1; i < 30; i++) {
            new Thread(()->{
                map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,5));
                System.err.println("当前线程为："+Thread.currentThread().getName()+":"+"\n"+map);
            },String.valueOf(i)).start();
        }
    }

    /**
     * 4、能够很好的解决并发安全问题，效率高，推荐使用
     */

    public static void concurrentHashMap(){
        Map<String,String> map = new ConcurrentHashMap<>();

        for (int i = 1; i < 30; i++) {
            new Thread(()->{
                map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,5));
                System.err.println("当前线程为："+Thread.currentThread().getName()+":"+"\n"+map);
            },String.valueOf(i)).start();

        }

    }
}
